package org.unidata.mdm.meta.context;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.unidata.mdm.core.context.AbstractModelChangeContext;
import org.unidata.mdm.core.service.segments.ModelUpsertStartExecutor;
import org.unidata.mdm.meta.configuration.TypeIds;
import org.unidata.mdm.meta.type.model.sourcesystem.SourceSystem;
import org.unidata.mdm.meta.util.ModelUtils;

/**
 * @author Mikhail Mikhailov on Oct 8, 2020
 */
public class UpsertSourceSystemsContext extends AbstractModelChangeContext {
    /**
     * GSVUID.
     */
    private static final long serialVersionUID = 7169865700344716584L;
    /**
     * Source systems updates.
     */
    private final List<SourceSystem> sourceSystemsUpdate;
    /**
     * Source systems deletes.
     */
    private final List<String> sourceSystemsDelete;
    /**
     * Constructor.
     */
    private UpsertSourceSystemsContext(UpsertSourceSystemsContextBuilder b) {
        super(b);
        this.sourceSystemsUpdate = Objects.isNull(b.sourceSystemsUpdate) ? Collections.emptyList() : b.sourceSystemsUpdate;
        this.sourceSystemsDelete = Objects.isNull(b.sourceSystemsDelete) ? Collections.emptyList() : b.sourceSystemsDelete;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String getTypeId() {
        return TypeIds.SOURCE_SYSTEMS_MODEL;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String getInstanceId() {
        // Source systems are singletons per storage id
        return ModelUtils.DEFAULT_MODEL_INSTANCE_ID;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String getStartTypeId() {
        return ModelUpsertStartExecutor.SEGMENT_ID;
    }
    /**
     * @return the sourceSystemsUpdate
     */
    public List<SourceSystem> getSourceSystemsUpdate() {
        return sourceSystemsUpdate;
    }
    /**
     * @return the sourceSystemsDelete
     */
    public List<String> getSourceSystemsDelete() {
        return sourceSystemsDelete;
    }

    public static UpsertSourceSystemsContextBuilder builder() {
        return new UpsertSourceSystemsContextBuilder();
    }
    /**
     * @author Mikhail Mikhailov on Oct 9, 2020
     */
    public static class UpsertSourceSystemsContextBuilder extends AbstractModelChangeContextBuilder<UpsertSourceSystemsContextBuilder> {
        /**
         * Source systems updates.
         */
        private List<SourceSystem> sourceSystemsUpdate;
        /**
         * Source systems deletes.
         */
        private List<String> sourceSystemsDelete;
        /**
         * Constructor.
         */
        private UpsertSourceSystemsContextBuilder() {
            super();
        }

        public UpsertSourceSystemsContextBuilder update(SourceSystem... ss) {
            if (ArrayUtils.isNotEmpty(ss)) {
                return update(Arrays.asList(ss));
            }
            return self();
        }

        public UpsertSourceSystemsContextBuilder update(Collection<SourceSystem> ss) {
            if (CollectionUtils.isNotEmpty(ss)) {
                if (sourceSystemsUpdate == null) {
                    sourceSystemsUpdate = new ArrayList<>();
                }

                sourceSystemsUpdate.addAll(ss);
            }
            return self();
        }

        public UpsertSourceSystemsContextBuilder delete(String... ss) {
            if (ArrayUtils.isNotEmpty(ss)) {
                return delete(Arrays.asList(ss));
            }
            return self();
        }

        public UpsertSourceSystemsContextBuilder delete(Collection<String> ss) {
            if (CollectionUtils.isNotEmpty(ss)) {
                if (sourceSystemsDelete == null) {
                    sourceSystemsDelete = new ArrayList<>();
                }

                sourceSystemsDelete.addAll(ss);
            }
            return self();
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public UpsertSourceSystemsContext build() {
            return new UpsertSourceSystemsContext(this);
        }
    }
}
